/*
    jME Terra package. A Terrain Engine for the Java Monkey Engine.
    Copyright (C) 2005-2006,  Tijl Houtbeckers
 
 **** LICENSE: ****
 
        This library is free software; you can redistribute it and/or
        modify it under the terms of the GNU Lesser General Public
        License as published by the Free Software Foundation,
        version 2.1.
 
        This library is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        Lesser General Public License for more details.
 
        You should have received a copy of the GNU Lesser General Public
        License along with this library; if not, write to the Free Software
        Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
 **** CONTACT: ****
 
    I can be reached through the jmonkeyengine.com forums (user "llama"),
    or the jmonkeyengine.com contact page:
    jmonkeyengine.com/index.php?option=com_contact&task=view&contact_id=5
 
 */

/**
 * @author Tijl Houtbeckers
 */

package org.llama.jmex.terra;

import com.jme.math.FastMath;
import com.jme.math.Vector3f;
import java.util.Random;
import com.jme.scene.SceneElement;
import com.jme.scene.TriMesh;
import com.jme.scene.VBOInfo;
import com.jme.scene.batch.TriangleBatch;
import com.jme.util.geom.BufferUtils;

public abstract class TerraMesh extends TriMesh {
    
    private static final long serialVersionUID = 1L;
    
    public int id = (new Random()).nextInt();
    
    public XYKey xy;
    public static final String K_MESH="me";
    
    
    public TerraMesh(String name) {
        super(name);
    }
    
    public abstract void buildTerra(TerraData terraData);
    
    public static VBOInfo vboinfo = null;
    
    
    
    public boolean hasLockedBounds() {
        return ((getLocks() & SceneElement.LOCKED_BOUNDS) != 0);
    }
    
    protected boolean deleted = false;
    
    protected boolean ditch = false;
    
    
    
    
////		if (this.getVBOInfo() == null && vboinfo != null) {
////			if (vboinfo.getVBOTextureID(0) > 0){
////	        	VBOInfo myvbo = vboinfo.copy();
////	        	myvbo.setVBOTextureID(0, vboinfo.getVBOTextureID(0));
////
////	        	if (myvbo.isVBOIndexEnabled())
////	        		myvbo.setVBOIndexID(vboinfo.getVBOIndexID());
////	        	setVBOInfo(myvbo);
////	        }
////		}
////		else if (this.getVBOInfo().getVBOVertexID() > 0 && this.getVertexBuffer() != null) {
////			this.setVertexBuffer(null);
////			this.setNormalBuffer(null);
//////			this.setVertexBuffer(null);
////
//////			this.setVertexBuffer(null);
////		}
//
//
//		if (getVBOInfo() != null)
//				System.out.println(getVBOInfo().getVBOIndexID());
//		super.draw(r);
//	}
    
    
    
    public abstract void cleanUp();
    
    
    
    private Vector3f store, calcVec1 = new Vector3f(), calcVec2 = new Vector3f(), calcVec3 = new Vector3f();
    public Vector3f calcSurfaceNormal(float x, float z, int blocksize, Vector3f stepScale) {
//        x /= stepScale.x;
//        z /= stepScale.z;
        
        float col = FastMath.floor(x);
        float row = FastMath.floor(z);
        
        if (col < 0 || row < 0 || col >= blocksize - 1 || row >= blocksize - 1) {
            return null;
        }
        float intOnX = x - col, intOnZ = z - row;
        
        if (store == null)
            store = new Vector3f();
        
        Vector3f topLeft = store, topRight = calcVec1, bottomLeft = calcVec2, bottomRight = calcVec3;
        
        int focalSpot = (int) (col + row * blocksize);
        TriangleBatch batch = getBatch(0);
        
        // find the heightmap point closest to this position (but will always
        // be to the left ( < x) and above (< z) of the spot.
        BufferUtils.populateFromBuffer(topLeft, batch.getNormalBuffer(),
                focalSpot);
        
        // now find the next point to the right of topLeft's position...
        BufferUtils.populateFromBuffer(topRight, batch.getNormalBuffer(),
                focalSpot + 1);
        
        // now find the next point below topLeft's position...
        BufferUtils.populateFromBuffer(bottomLeft, batch.getNormalBuffer(),
                focalSpot + blocksize);
        
        // now find the next point below and to the right of topLeft's
        // position...
        BufferUtils.populateFromBuffer(bottomRight, batch.getNormalBuffer(),
                focalSpot + blocksize + 1);
        
        // Use linear interpolation to find the height.
        topLeft.interpolate(topRight, intOnX);
        bottomLeft.interpolate(bottomRight, intOnX);
        topLeft.interpolate(bottomLeft, intOnZ);
        return topLeft.normalizeLocal();
    }
}
